

from huobi.client.account import AccountClient
from huobi.client.generic import GenericClient
from huobi.client.market import MarketClient
from huobi.client.trade import TradeClient
from huobi.constant.definition import AccountBalanceUpdateType, OrderSource, OrderType

from huobi.privateconfig import *
from huobi.utils.log_info import Log
from quant_define import ApiTrading, QuantState, SymbolPartition, SymbolState
from symbols.quant_symbol_new_symbol import QuantSymbolNewSymbol

class QuantMgr:

    __instance = None

    @staticmethod
    def getinstance():
        if QuantMgr.__instance is None:
            QuantMgr.__instance = object.__new__(QuantMgr)
            QuantMgr.__instance.init()

        return QuantMgr.__instance

    def __init__(self) -> None:
        return SyntaxError("please use getinstance!!!")

    def init(self):
        self.m_account_client = AccountClient(api_key=p_api_key,secret_key=p_secret_key)
        self.m_generic_client = GenericClient()
        self.m_trade_client = TradeClient(api_key=p_api_key,secret_key=p_secret_key)
        self.m_market_client = MarketClient()
        self.m_cur_symbols = []
        self.m_quant_symbols = {}
        self.m_offline_symbols = {}
        self.m_online_symbols = {}
        self.m_suspend_symbols = {}

    def update(self):
        self.check_new_symbols()
        self.check_symbol_quant()

    def check_new_symbols(self):
        cur_symbols = self.m_generic_client.get_exchange_symbols()
        
        if not bool(self.m_online_symbols) and not bool(self.m_offline_symbols):
            for symbol in cur_symbols:
                if symbol.state == SymbolState.Online :
                    self.m_online_symbols[symbol.symbol] = True
                elif symbol.state == SymbolState.Offline:
                    self.m_offline_symbols[symbol.symbol] = True
                else:
                    self.m_suspend_symbols[symbol.symbol] = True
            if False:
                for info in self.m_cur_symbols:
                    if info.symbol == "btcusdt":
                        quant_symbol_info = QuantSymbolNewSymbol(self.m_account_client,
                                self.m_generic_client,self.m_trade_client,self.m_market_client)
                        quant_symbol_info.m_symbol = info
                        quant_symbol_info.m_state = QuantState.Buying
                        quant_symbol_info.m_buy_orderid = 464296619840880
                        self.m_quant_symbols[info.symbol] = quant_symbol_info
                        break
            return

        for symbol in cur_symbols:
            # 上线
            if symbol.state == SymbolState.Online :
                #已上线
                if symbol.symbol in self.m_online_symbols:
                    pass
                #刚上线
                else:
                    if symbol.symbol in self.m_offline_symbols:
                        del self.m_offline_symbols[symbol.symbol]
                    if symbol.symbol in self.m_suspend_symbols:
                        del self.m_suspend_symbols[symbol.symbol]

                    self.m_online_symbols[symbol.symbol] = True

                    if  symbol.quote_currency == "usdt" and \
                        symbol.api_trading == ApiTrading.enabled and \
                        symbol.symbol_partition != SymbolPartition.pioneer and \
                        symbol.symbol_partition != SymbolPartition.bifurcation :
                            Log.info("[check_new_symbols]: new symbol online symbol = {0}".format(symbol.symbol))
                            quant_symbol_info = QuantSymbolNewSymbol(self.m_account_client,
                                self.m_generic_client,self.m_trade_client,self.m_market_client)
                            quant_symbol_info.m_symbol = symbol
                            self.m_quant_symbols[symbol.symbol] = quant_symbol_info
                    else:
                        Log.info("[check_new_symbols]: new symbol but can trade apiTrade={0}, partition={1}, currency={2}".format(symbol.api_trading,symbol.symbol_partition,symbol.quote_currency))
            elif symbol.state == SymbolState.Offline:
                if symbol.symbol in self.m_suspend_symbols:
                    del self.m_suspend_symbols[symbol.symbol]

                if not symbol.symbol in self.m_offline_symbols:
                    Log.info("[check_new_symbols]: off line : {0}".format(symbol.symbol))
                    self.m_offline_symbols[symbol.symbol] = True
            else:
                if symbol.symbol in self.m_offline_symbols:
                    del self.m_offline_symbols[symbol.symbol]

                if not symbol.symbol in self.m_suspend_symbols:
                    Log.info("[check_new_symbols]: wait for on line : {0}".format(symbol.symbol))
                    self.m_suspend_symbols[symbol.symbol] = True


    def check_symbol_quant(self):
        
        to_del = []
        for key,quant_symbol in self.m_quant_symbols.items():
            quant_symbol.update()
            if quant_symbol.die():
                to_del.append(key)

        for symbol in to_del:
            del self.m_quant_symbols[symbol]
        
    
    def create_order(self, symbol:str, price:float, amount:float, order_type:OrderType):
        Log.info("try create order symbol={0}, price={1}, amount={2}, order_type={3}".format(symbol,price,amount,order_type))
        orderid = self.m_trade_client.create_order(symbol,p_account_id,order_type,amount,price,source=OrderSource.API)
        Log.info("create order orderid = {0}".format(orderid))
        return orderid

    def get_balance(self,currency):
        balances = self.m_account_client.get_balance(p_account_id)
        for balance in balances:
            if balance.currency == currency and balance.type == AccountBalanceUpdateType.TRADE:
                return float(balance.balance)